package study1;

import java.util.Stack;

public class PreorderInorderPostorderTraversal {
    static class TreeNode {
        public char val;         // 节点存储的字符值（如 'A', 'B' 等）
        public TreeNode left;    // 左子节点指针
        public TreeNode right;   // 右子节点指针

        // 构造函数，初始化节点值，左右子节点默认为 null
        public TreeNode(char val) {
            this.val = val;
        }
    }


    // 创建并返回一个预定义结构的二叉树
    public TreeNode createTree() {
        // 创建所有节点，节点值从 'A' 到 'H'
        TreeNode A = new TreeNode('A');
        TreeNode B = new TreeNode('B');
        TreeNode C = new TreeNode('C');
        TreeNode D = new TreeNode('D');
        TreeNode E = new TreeNode('E');
        TreeNode F = new TreeNode('F');
        TreeNode G = new TreeNode('G');
        TreeNode H = new TreeNode('H');

        // 构建树结构
        A.left = B;   // A 的左子节点是 B
        A.right = C;  // A 的右子节点是 C
        B.left = D;   // B 的左子节点是 D
        B.right = E;  // B 的右子节点是 E
        C.left = F;   // C 的左子节点是 F
        C.right = G;  // C 的右子节点是 G
        E.right = H;  // E 的右子节点是 H（注意：E 的左子节点未设置，默认为 null）

        return A; // 返回根节点 A
    }

    // 前序遍历：根 -> 左 -> 右
    public void preOrder(TreeNode root) {
        if (root == null) return;       // 递归终止条件：空节点
        System.out.print(root.val + " "); // 访问根节点
        preOrder(root.left);             // 递归遍历左子树
        preOrder(root.right);            // 递归遍历右子树
    }

    public static void preOrderIteration(TreeNode head) {
        if (head == null) {
            return;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(head);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            System.out.print(node.val + " ");
            if (node.right != null) {
                stack.push(node.right);
            }
            if (node.left != null) {
                stack.push(node.left);
            }
        }
    }


    public static void preOrderMorris(TreeNode head) {
        if (head == null) {
            return;
        }
        TreeNode cur1 = head;
        TreeNode cur2 = null;
        while (cur1 != null) {
            cur2 = cur1.left;
            if (cur2 != null) {
                while (cur2.right != null && cur2.right != cur1) {
                    cur2 = cur2.right;
                }
                if (cur2.right == null) {
                    cur2.right = cur1;
                    System.out.print(cur1.val + " ");
                    cur1 = cur1.left;
                    continue;
                } else {
                    cur2.right = null;
                }
            } else {
                System.out.print(cur1.val + " ");
            }
            cur1 = cur1.right;
        }
    }





    // 中序遍历：左 -> 根 -> 右
    public void inOrder(TreeNode root) {
        if (root == null) return;        // 递归终止条件：空节点
        inOrder(root.left);              // 递归遍历左子树
        System.out.print(root.val + " "); // 访问根节点
        inOrder(root.right);             // 递归遍历右子树
    }

    public static void inOrderIteration(TreeNode head) {
        if (head == null) {
            return;
        }
        TreeNode cur = head;
        Stack<TreeNode> stack = new Stack<>();
        while (!stack.isEmpty() || cur != null) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode node = stack.pop();
            System.out.print(node.val + " ");
            if (node.right != null) {
                cur = node.right;
            }
        }
    }


    public static void inOrderMorris(TreeNode head) {
        if (head == null) {
            return;
        }
        TreeNode cur1 = head;
        TreeNode cur2 = null;
        while (cur1 != null) {
            cur2 = cur1.left;
            //构建连接线
            if (cur2 != null) {
                while (cur2.right != null && cur2.right != cur1) {
                    cur2 = cur2.right;
                }
                if (cur2.right == null) {
                    cur2.right = cur1;
                    cur1 = cur1.left;
                    continue;
                } else {
                    cur2.right = null;
                }
            }
            System.out.print(cur1.val + " ");
            cur1 = cur1.right;
        }
    }




    // 后序遍历：左 -> 右 -> 根
    public void postOrder(TreeNode root) {
        if (root == null) return;         // 递归终止条件：空节点
        postOrder(root.left);            // 递归遍历左子树
        postOrder(root.right);           // 递归遍历右子树
        System.out.print(root.val + " ");  // 访问根节点
    }


    public static void postOrderIteration(TreeNode head) {
        if (head == null) {
            return;
        }
        Stack<TreeNode> stack1 = new Stack<>();
        Stack<TreeNode> stack2 = new Stack<>();
        stack1.push(head);
        while (!stack1.isEmpty()) {
            TreeNode node = stack1.pop();
            stack2.push(node);
            if (node.left != null) {
                stack1.push(node.left);
            }
            if (node.right != null) {
                stack1.push(node.right);
            }
        }
        while (!stack2.isEmpty()) {
            System.out.print(stack2.pop().val + " ");
        }
    }


    public static void postOrderIteration2(TreeNode head) {
        if (head == null) {
            return;
        }
        TreeNode cur = head;
        Stack<TreeNode> stack = new Stack<>();
        stack.push(head);
        while (!stack.isEmpty()) {
            TreeNode peek = stack.peek();
            if (peek.left != null && peek.left != cur && peek.right != cur) {
                stack.push(peek.left);
            } else if (peek.right != null && peek.right != cur) {
                stack.push(peek.right);
            } else {
                System.out.print(stack.pop().val + " ");
                cur = peek;
            }
        }
    }



    //  后序Morris
    public static void postOrderMorris(TreeNode head) {
        if (head == null) {
            return;
        }
        TreeNode cur1 = head;//遍历树的指针变量
        TreeNode cur2 = null;//当前子树的最右节点
        while (cur1 != null) {
            cur2 = cur1.left;
            if (cur2 != null) {
                while (cur2.right != null && cur2.right != cur1) {
                    cur2 = cur2.right;
                }
                if (cur2.right == null) {
                    cur2.right = cur1;
                    cur1 = cur1.left;
                    continue;
                } else {
                    cur2.right = null;
                    postMorrisPrint(cur1.left);
                }
            }
            cur1 = cur1.right;
        }
        postMorrisPrint(head);
    }
    //打印函数
    public static void postMorrisPrint(TreeNode head) {
        TreeNode reverseList = postMorrisReverseList(head);
        TreeNode cur = reverseList;
        while (cur != null) {
            System.out.print(cur.val + " ");
            cur = cur.right;
        }
        postMorrisReverseList(reverseList);
    }
    //翻转单链表
    public static TreeNode postMorrisReverseList(TreeNode head) {
        TreeNode cur = head;
        TreeNode pre = null;
        while (cur != null) {
            TreeNode next = cur.right;
            cur.right = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }



}
